home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '87 / Source ƒ.sea / Source ƒ / Pascal ƒ / TOOLS / tools.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-02-27  |  7.5 KB  |  488 lines  |  [TEXT/MACA]

  1. /* TOOLS.C: expression parser used by grep. */
  2.  
  3. #include    "stdio.h"
  4. #include    "tools.h"
  5.  
  6. int amatch(lin,pat,boln)
  7. char    *lin, *boln ;
  8. TOKEN    *pat ;
  9. {
  10.     char    *bocl, *rval, *strstart ;
  11. #ifdef    DEBUG
  12.     fprintf(stderr, "amatch entered\n") ;
  13. #endif
  14.     if (pat==0)
  15.         return(0) ;
  16.     strstart=lin ;
  17.     while(pat)
  18.     {
  19.         if(pat->tok == CLOSURE && pat->next)
  20.         {
  21.             pat = pat->next ;
  22.             bocl = lin ;
  23.             while(*lin && omatch(&lin, pat))  ;
  24.             if(pat = pat->next)
  25.             {
  26.                 while(bocl <= lin)
  27.                 {
  28.                     if(rval = amatch(lin, pat, boln))
  29.                     {
  30.                         return(rval) ;
  31.                     }
  32.                     else
  33.                         --lin ;
  34.                 }
  35.                 return(0) ;
  36.             }
  37.         }
  38.         else if(omatch(&lin, pat, boln))
  39.         {
  40.             pat=pat->next ;
  41.         }
  42.         else
  43.         {
  44.             return(0) ;
  45.         }
  46.     }
  47.     return(maximum(strstart, --lin)) ;
  48. }
  49.  
  50.  
  51. delete (ch, str)
  52. int        ch ;
  53. char    *str ;
  54. {
  55. #ifdef    DEBUG
  56.     fprintf(stderr, "delete entered.\n") ;
  57. #endif
  58.     ch &= 0xff ;
  59.     while(*str && *str != ch)
  60.         str++ ;
  61.     while(*str)
  62.     {
  63.         *str = *(str+1) ;
  64.         str++ ;
  65.     }
  66. }
  67.  
  68.  
  69.  
  70. int dodash (delim, src, dest, maxccl)
  71. int    delim, maxccl ;
  72. char    **src, *dest ;
  73. {
  74.     char    *dstart ;
  75.     int    k, at_begin ;
  76.     char        *sptr ;
  77. #ifdef    DEBUG
  78.     fprintf(stderr, "dodash entered\n") ;
  79. #endif
  80.     dstart = dest ;
  81.     sptr = *src ;
  82.     at_begin = 1 ;
  83.     while(*sptr && (*sptr != delim) && (dstart-dest < maxccl))
  84.     {
  85.         if(*sptr == ESCAPE)
  86.         {
  87.             *dest++ = esc(&sptr) ;
  88.             sptr++ ;
  89.         }
  90.         else if (*sptr != '-')
  91.             *dest++ = *sptr++ ;
  92.         else if (at_begin || *(sptr+1) == delim)
  93.             *dest++ = '-' ;
  94.         else if ( *(sptr-1)<= *(sptr+1))
  95.         {
  96.             sptr++ ;
  97.             for(k= *(sptr-2); ++k <= *sptr;)
  98.                 *dest++ = k ;
  99.             sptr++ ;
  100.         }
  101.         else
  102.         {
  103.             return(0) ;
  104.         }
  105.         at_begin = 0 ;
  106.     }
  107.     *dest++ = '\000' ;
  108.     *src = sptr ;
  109.     return(dest - dstart) ;
  110. }
  111.  
  112.  
  113. int esc (s)
  114. char    **s ;
  115. {
  116.     int    rval ;
  117. #ifdef    DEBUG
  118.     fprintf(stderr, "esc entered.\n") ;
  119. #endif
  120.     if(**s != ESCAPE)
  121.     {
  122.         rval = **s ;
  123.     }
  124.     else
  125.     {
  126.         (*s)++ ;
  127.         switch(toupper(**s))
  128.         {
  129.         case    '\000':    rval = ESCAPE ;    break ;
  130.         case    'S':    rval = ' ' ;    break ;
  131.         case    'N':    rval = '\n' ;    break ;
  132.         case    'T':    rval = '\t' ;    break ;
  133.         case    'B':    rval = '\b' ;    break ;
  134.         case    'R':    rval = '\r' ;    break ;
  135.         default:    rval = **s ;    break ;
  136.         }
  137.     }
  138.     return(rval) ;
  139. }
  140.  
  141.  
  142.  
  143.  
  144. TOKEN *getpat (arg)
  145. char    *arg ;
  146. {
  147. #ifdef    DEBUG
  148.     fprintf(stderr, "getpat entered.\n") ;
  149. #endif
  150.     return(makepat(arg, '\000')) ;
  151. }
  152.  
  153.  
  154.  
  155. insert (ch, str)
  156. int    ch ;
  157. char    *str ;
  158. {
  159.     char    *bp ;
  160. #ifdef    DEBUG
  161.     fprintf(stderr, "insert entered.\n") ;
  162. #endif
  163.     bp = str ;
  164.     while(*str)
  165.         str++ ;
  166.     do
  167.     {
  168.         *(str+1) = *str ;
  169.         str-- ;
  170.     } while (str >= bp) ;
  171.     *bp = ch ;
  172. }
  173.  
  174.  
  175.  
  176. char *in_string (delim, str)
  177. int    delim ;
  178. char    *str ;
  179. {
  180. #ifdef    DEBUG
  181.     fprintf(stderr, "in_string entered.\n") ;
  182. #endif
  183.     delim &= 0x7f ;
  184.     while(*str && *str != delim)
  185.         str++ ;
  186.     return(*str ? str : 0) ;
  187. }
  188.  
  189.  
  190.  
  191.  
  192. int isalphanum (c)
  193. int    c ;
  194. {
  195. #ifdef    DEBUG
  196.     fprintf(stderr, "isalphanum entered.\n") ;
  197. #endif
  198.     return(    ('a' <= c && c <= 'z') ||
  199.         ('A' <= c && c <= 'Z') ||
  200.         ('0' <= c && c <= '9')
  201.           ) ;
  202. }
  203.  
  204.  
  205.  
  206.  
  207. TOKEN *makepat (arg, delim)
  208. char    *arg ;
  209. int    delim ;
  210. {
  211.     TOKEN    *head, *tail ;
  212.     TOKEN    *ntok ;
  213.     char    buf[CLS_SIZE] ;
  214.     int    error ;
  215.     char    *malloc() ;
  216. #ifdef    DEBUG
  217.     fprintf(stderr, "makepat entered.\n") ;
  218. #endif
  219.     if(*arg=='\0' || *arg==delim || *arg=='\n' || *arg==CLOSURE)
  220.         return(0) ;
  221.     error = 0 ;
  222.     head = 0 ;
  223.     tail = 0 ;
  224.     while(*arg && *arg != delim && *arg != '\n' && !error)
  225.     {
  226.         ntok = malloc(TOKSIZE) ;
  227.         ntok->string = &(ntok->lchar) ;
  228.         ntok->lchar = '\000' ;
  229.         ntok->next = 0 ;
  230.         switch(*arg)
  231.         {
  232.         case ANY:    ntok->tok = ANY ;    break ;
  233.         case BOL:    if(head==0)
  234.                     ntok->tok = BOL ;
  235.                 else
  236.                     error = 1 ;
  237.                 break ;
  238.         case EOL:    if(*(arg+1) == delim|| *(arg+1) == '\000'
  239.                             || *(arg+1) == '\n')
  240.                     ntok->tok = EOL ;
  241.                 else
  242.                     error = 1 ;
  243.                 break ;
  244.         case CCL:    if(*(arg+1) == NEGATE)
  245.                 {
  246.                     ntok->tok = NCCL ;
  247.                     arg += 2 ;
  248.                 }
  249.                 else
  250.                 {
  251.                     ntok->tok = CCL ;
  252.                     arg++ ;
  253.                 }
  254.                 error = dodash(CCLEND, &arg, buf, CLS_SIZE) ;
  255.                 if (error != 0)
  256.                 {
  257.                     ntok->string = malloc(error) ;
  258.                     strcpy(ntok->string, buf) ;
  259.                     error = 0 ;
  260.                 }
  261.                 break ;
  262.         case CLOSURE:    if(head != 0)
  263.                 {
  264.                     switch (tail->tok)
  265.                     {
  266.                     case BOL:
  267.                     case EOL:
  268.                     case CLOSURE:    return(0) ;
  269.                     default:    ntok->tok = CLOSURE ;
  270.                     }
  271.                 }
  272.                 break ;
  273.         default:    ntok->tok = LITCHAR;
  274.                 ntok->lchar = esc(&arg) ;
  275.         }
  276.         if(error || ntok == 0)
  277.         {
  278.             unmakepat(head) ;
  279.             return(0) ;
  280.         }
  281.         else if (head == 0)
  282.         {
  283.             ntok->next = 0 ;
  284.             head = tail = ntok ;
  285.         }
  286.         else if (ntok->tok != CLOSURE)
  287.         {
  288.             tail->next = ntok ;
  289.             ntok->next = tail ;
  290.             tail = ntok ;
  291.         }
  292.         else if(head != tail)
  293.         {
  294.             (tail->next)->next = ntok ;
  295.             ntok->next = tail ;
  296.         }
  297.         else
  298.         {
  299.             ntok->next = head ;
  300.             tail->next = ntok ;
  301.             head = ntok ;
  302.         }
  303.         arg++ ;
  304.     }
  305.     tail->next = 0;
  306.     return(head) ;
  307. }
  308.  
  309.  
  310.  
  311.  
  312. char *matchs (line, pat, ret_endp)
  313. char    *line ;
  314. TOKEN    *pat ;
  315. int    ret_endp ;
  316. {
  317.     char    *rval, *bptr ;
  318. #ifdef    DEBUG
  319.     fprintf(stderr, "matchs entered.\n") ;
  320. #endif
  321.     bptr = line ;
  322.     while(*line)
  323.     {
  324.         if((rval = amatch(line, pat, bptr)) == 0)
  325.         {
  326.             line++ ;
  327.         }
  328.         else
  329.         {
  330.             rval = ret_endp ? rval : line ;
  331.             break ;
  332.         }
  333.     }
  334.     return(rval) ;
  335. }
  336.  
  337.  
  338.  
  339.  
  340. stoupper (str)
  341. char    *str ;
  342. {
  343.     char    *rval ;
  344. #ifdef    DEBUG
  345.     fprintf(stderr, "stoupper entered.\n") ;
  346. #endif
  347.     rval = str ;
  348.     while(*str)
  349.     {
  350.         if('a' <= *str && *str <= 'z')
  351.             *str -= ('a' - 'A') ;
  352.         str++ ;
  353.     }
  354. }
  355.  
  356.  
  357.  
  358.  
  359. int maximum (x, y)
  360. int    x, y ;
  361. {
  362.     return ((x>y) ? x : y) ;
  363. }
  364.  
  365.  
  366.  
  367.  
  368. int omatch (linp, pat, boln)
  369. char    **linp, *boln ;
  370. TOKEN    *pat ;
  371. {
  372.     int    advance ;
  373. #ifdef    DEBUG
  374.     fprintf(stderr, "omatch entered.\n") ;
  375. #endif
  376.     advance = -1 ;
  377.     if(**linp)
  378.     {
  379.         switch(pat->tok)
  380.         {
  381.         case LITCHAR:    if(**linp == pat->lchar)
  382.                     advance = 1 ;
  383.                 break ;
  384.         case BOL:    if(*linp == boln)
  385.                     advance = 0 ;
  386.                 break ;
  387.         case ANY:    if(**linp != '\n')
  388.                     advance = 1 ;
  389.                 break ;
  390.         case EOL:    if(**linp == '\n')
  391.                     advance = 0 ;
  392.                 break ;
  393.         case CCL:    if(in_string(**linp, pat->string))
  394.                     advance = 1;
  395.                 break ;
  396.         case NCCL:    if( ! in_string (**linp, pat->string))
  397.                     advance = 1 ;
  398.                 break ;
  399.         default:    printf("omatch: can't happen\n") ;
  400.         }
  401.     }
  402.     if(advance >= 0)
  403.         *linp += advance ;
  404.     return(++advance) ;
  405. }
  406.  
  407.  
  408.  
  409.  
  410. pr_line (ln)
  411. char    *ln ;
  412. {
  413. #ifdef    DEBUG
  414.     fprintf(stderr, "pr_line entered.\n") ;
  415. #endif
  416.     for( ; *ln; ln++)
  417.     {
  418.         if((' ' <= *ln) && (*ln <= '~'))
  419.             putchar(*ln) ;
  420.         else
  421.         {
  422.             printf("\\0x%02x", *ln) ;
  423.             if(*ln == '\n')
  424.                 putchar('\n') ;
  425.         }
  426.     }
  427. }
  428.  
  429.  
  430.  
  431.  
  432. pr_tok (head)
  433. TOKEN    *head ;
  434. {
  435.     char    *str ;
  436. #ifdef    DEBUG
  437.     fprintf(stderr, "pr_token netered.\n") ;
  438. #endif
  439.     for( ; head; head = head->next)
  440.     {
  441.         switch(head->tok)
  442.         {
  443.         case BOL:    str="BOL" ;    break ;
  444.         case EOL:    str="EOL" ;    break ;
  445.         case ANY:    str="ANY" ;    break ;
  446.         case LITCHAR:    str="LITCHAR" ;    break ;
  447.         case ESCAPE:    str="ESCAPE" ;    break ;
  448.         case CCL:    str="CCL" ;    break ;
  449.         case CCLEND:    str="CCLEND" ;    break ;
  450. /*        case NEGATE:    str="NEGATE" ;    break ;  */  /* dup case constant */
  451.         case NCCL:    str="NCCL" ;    break ;
  452.         case CLOSURE:    str="CLOSURE" ;    break ;
  453.         default:    str="**** unknown ****" ;
  454.         }
  455.         printf("%-8s at: 0x%x, ", str, head) ;
  456.         if(head->tok == CCL || head->tok == NCCL)
  457.             printf("string =[%s]=, ", head->string) ;
  458.         else if (head->tok == LITCHAR)
  459.             printf("lchar = %c, ", head->lchar) ;
  460.         printf("next = 0x%x\n", head->next) ;
  461.     }
  462.     putchar("\n") ;
  463. }
  464.  
  465.  
  466.  
  467.  
  468. unmakepat (head)
  469. TOKEN    *head ;
  470. {
  471.     TOKEN *old_head ;
  472. #ifdef    DEBUG
  473.     fprintf(stderr, "unmakepat entered.\n") ;
  474. #endif
  475.     while(head)
  476.     {
  477.         switch(head->tok)
  478.         {
  479.         case CCL:
  480.         case NCCL:    free(head->string) ;
  481.         default:    old_head = head ;
  482.                 head = head->next ;
  483.                 free(old_head) ;
  484.                 break ;
  485.         }
  486.     }
  487. }
  488.